// ProjectName: go-learn-demo
// PackageName: _3_basic
// Description:
// Author: hy.bai
// Date: 2025-07-31 15:29

package timeybxb

import (
	"fmt"
	"time"
)

// 日期时间类型的数据
func TestCurrnetTime() {
	// 1.获取当前系统时间
	var currentTime = time.Now()
	fmt.Printf("当前时间是:%T,值是:%v\n", currentTime, currentTime)
	// 打印:当前时间是:time.Time,值是:2025-07-31 15:36:25.8443707 +0800 CST m=+0.000000001

	// 2.格式化当前时间
	format := currentTime.Format("2006-01-02 15:04:05") // 2006-01-02 15:04:05是固定写法，而且必须这样写
	fmt.Printf("格式化后的时间是:%v\n", format)
	// 打印:格式化后的时间是:2025-07-31 15:36:25

	// 3.当前时间转换成时间戳
	unitSecound := currentTime.Unix() // 获取时间戳的秒数。即：从1970年1月1日开始到现在多少秒的时间
	fmt.Printf("当前时间戳是:%v\n", unitSecound)
	// 打印:当前时间戳是:1690601925

	// 4.字符串时间转时间对象
	location, _ := time.LoadLocation("Asia/Shanghai") // 指定日期时间时区
	timeStr := "2025-07-31 15:36:25"
	// 解析字符串类型的日期
	// layout参数是日期格式。value是实际的字符串类型的日期值。location参数是时区。
	if timeObj, err := time.ParseInLocation("2006-01-02 15:04:05", timeStr, location); err != nil {
		fmt.Println("字符串时间转时间对象失败")
	} else {
		fmt.Printf("字符串时间转时间对象成功:%T, %v\n", timeObj, timeObj)
		// 打印:字符串时间转时间对象成功:time.Time, 2000-07-31 15:36:25 +0800 CST
	}
}

// 获取时间对象的年、月、日、时、分、秒，并进行格式化时间
func TestSprintfTime() {
	// 获取当前系统时间
	currentTime := time.Now()
	year := currentTime.Year()
	month := currentTime.Month()
	day := currentTime.Day()
	hour := currentTime.Hour()
	minute := currentTime.Minute()
	second := currentTime.Second()
	format := fmt.Sprintf("%d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, minute, second)
	// %02d中的2表示宽度，如果整数不够2列就补上0。例如:6月会格式化为"06"
	fmt.Println(format) // 打印结果：2025-07-31 16:55:37
}

func TestTimeUnix() {
	currentTime := time.Now()        // 获取当前时间
	secound := currentTime.Unix()    // 返回从January 1, 1970 UTC到指定时间点的已过秒数
	milli := currentTime.UnixMilli() // 返回毫秒
	micro := currentTime.UnixMicro() // 返回微妙
	nano := currentTime.UnixNano()   // 返回纳秒
	fmt.Println(secound, milli, micro, nano)
}

func TestTimeUnixFormat() {
	currentTime := time.Now()                        // 获取当前时间
	timeObj1 := time.Unix(currentTime.Unix(), 0)     // 使用秒，将时间戳转为时间格式
	timeObj2 := time.Unix(0, currentTime.UnixNano()) // 使用纳秒，将时间戳转为时间格式
	fmt.Println(timeObj1, timeObj2)
	// 打印结果：timeObj1和timeObj2是相同的值：2025-07-31 18:45:35 +0800 CST 2025-07-31 18:45:35.5051179 +0800 CST
	// ---------------------------
	timeObj := timeObj1
	fmt.Println(timeObj)
	year := timeObj.Year()
	month := timeObj.Month()
	day := timeObj.Day()
	hour := timeObj.Hour()
	minute := timeObj.Minute()
	second := timeObj.Second()
	format := fmt.Sprintf("%d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, minute, second)
	// %02d中的2表示宽度，如果整数不够2列就补上0。例如:6月会格式化为"06"
	fmt.Println(format) // 打印结果：2025-07-31 18:22:00
}

// 测试时间间隔
func TestTimeDuration() {
	fmt.Printf("开始执行时间:%v\n", time.Now())
	time.Sleep(time.Second * 5) // 睡眠5秒
	time.Sleep(time.Minute * 5) // 睡眠5分钟
	fmt.Printf("结束执行时间:%v\n", time.Now())

	// 打印结果:
	//	开始执行时间:2025-07-31 18:53:36.5286456 +0800 CST m=+0.000000001
	//	结束执行时间:2025-07-31 18:53:41.5433165 +0800 CST m=+5.014670901
}

func TestFormatTime() {
	currentTime := time.Now()
	// 格式化的模板为Go的出生时间2006年1月2号15点04分 Mon Jan
	// 格式化为24小时制
	result24 := currentTime.Format("2006-01-02 15:04:05.000 Mon Jan")
	// 格式化为12小时制
	result12 := currentTime.Format("2006-01-02 03:04:05.000 PM Mon Jan")
	fmt.Println(result24) // 2025-07-31 19:06:33.241 Thu Jul
	fmt.Println(result12) // 2025-07-31 07:06:33.241 PM Thu Jul
}

// 格式化的字符串时间转时间对象
func TestStringToTime() {
	location, _ := time.LoadLocation("Asia/Shanghai") // 指定日期时间时区
	timeStr := "2020-07-31 15:36:25"
	// 解析字符串类型的日期
	// layout参数是日期格式。value是实际的字符串类型的日期值。location参数是时区。
	timeObj, err := time.ParseInLocation("2006-01-02 15:04:05", timeStr, location)
	if err != nil {
		fmt.Println("字符串时间转时间对象失败")
	} else {
		fmt.Printf("字符串时间转时间对象成功:%T, %v\n", timeObj, timeObj)
		// 打印:字符串时间转时间对象成功:time.Time, 2000-07-31 15:36:25 +0800 CST
	}
}
func TestTimeAdd() {
	location, _ := time.LoadLocation("Asia/Shanghai") // 指定日期时间时区
	timeStr := "2020-07-31 15:36:25"
	// 解析字符串类型的日期
	// layout参数是日期格式。value是实际的字符串类型的日期值。location参数是时区。
	timeObj, _ := time.ParseInLocation("2006-01-02 15:04:05", timeStr, location)

	duration1, _ := time.ParseDuration("10s") // 10秒后

	result1 := timeObj.Add(duration1) // 在指定的时间点上增加10秒
	fmt.Println("result1:", result1)
	// 打印结果是:result1: 2020-07-31 15:36:35 +0800 CST

	duration2, _ := time.ParseDuration("-10s") // 10秒前
	result2 := timeObj.Add(duration2)          // 在指定的时间点上减10秒
	fmt.Println("result2:", result2)
	// 打印结果是:result2: 2020-07-31 15:36:15 +0800 CST
}

// 求两个时间点的差
func TestTimeSub() {
	location, _ := time.LoadLocation("Asia/Shanghai") // 指定日期时间时区
	timeStr := "2025-07-31 15:36:25"
	// 解析字符串类型的日期
	// layout参数是日期格式。value是实际的字符串类型的日期值。location参数是时区。
	startTime, _ := time.ParseInLocation("2006-01-02 15:04:05", timeStr, location)
	currentTime := time.Now()
	// 求两个时间点之间差
	hours := currentTime.Sub(startTime).Hours() // 结果是float64类型
	fmt.Printf("相差的小时数:%f\n", hours)
}
